package rs.util;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringUtil {
		
	/**
	 * 格式化${0}格式的字符串
	 * @param source
	 * @param replacements
	 * @return
	 */
	public static String format$(String source, String ... replacements ){
		return format$WithURLSupport(source, false, replacements);
	}
	
	/**
	 * 格式化${key}格式的字符串
	 * @param source
	 * @param rpl
	 * @return
	 */
	public static String format$(String source, Map<String, Object> rpl){
		return format$WithURLSupport(source, rpl, false);
	}
	
	/**
	 * 格式化${0}格式的字符串,并做url编码
	 * @param source
	 * @param replacements
	 * @return
	 */
	public static String format$URL(String source, String ... replacements ){
		return format$WithURLSupport(source, true, replacements);
	}
	
	/**
	 * 格式化${key}格式的字符串,并做url编码
	 * @param source
	 * @param rpl
	 * @return
	 */
	public static String format$URL(String source, Map<String, Object> rpl){
		return format$WithURLSupport(source, rpl, true);
	}
	
	
	
	private static String format$WithURLSupport(String source, boolean isUrlFormat, String ... replacements ){
		String splitor = "###";
		String splitorTmp = "##%##";
		source = source.replaceAll(splitor, splitorTmp);
		source = source.replaceAll("\\$\\{(\\d+)\\}", splitor + "$1" + splitor);
		String[] splits = source.split(splitor);
		for(int i=1; i < splits.length; i+=2){
			try{
				splits[i] = replacements[Integer.parseInt(splits[i])];
			} catch (Exception e) {
				splits[i] = "";
			}
			if(isUrlFormat
					&& (!splits[i].trim().startsWith("http"))){
				splits[i] = encodeURIComponent(splits[i]);
			}
		}
		StringBuilder sb = new StringBuilder(splits.length);
		for (String s : splits) {
			sb.append(s);
		}
		source = sb.toString();
		source = source.replaceAll(splitorTmp, splitor);
		return source;
	}
	
	private static String format$WithURLSupport(String source, Map<String, Object> rpl, boolean isUrlFormat){
		String splitor = "###";
		String splitorTmp = "##%##";
		source = source.replaceAll(splitor, splitorTmp);
		source = source.replaceAll("\\$\\{([^\\}]*)\\}", splitor + "$1" + splitor);
		String[] splits = source.split(splitor);
		for(int i=1; i < splits.length; i+=2){
			splits[i] = rpl.get(splits[i]) == null ? "" : rpl.get(splits[i]).toString();
			if(isUrlFormat
					&& (!splits[i].trim().startsWith("http"))){
				splits[i] = encodeURIComponent(splits[i]);
			}
		}
		StringBuilder sb = new StringBuilder(splits.length);
		for (String s : splits) {
			sb.append(s);
		}
		source = sb.toString();
		source = source.replaceAll(splitorTmp, splitor);
		return source;
	}
	
	public static String encodeURIComponent(String input){
		try {
			return URLEncoder.encode(input, "utf8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return "";
		}
	}
	
	/**
	 * 获得字符串中第一个匹配所给正则表达式的值,如果没有,返回默认值
	 * @param content 原字符串
	 * @param patternString 正则表达式
	 * @param defaultValue 默认值
	 * @return 匹配结果,若没有,返回默认值
	 */
	public static String find(String content, String patternString, String defaultValue){
		String ret = defaultValue;
		Pattern pattern = getPattern(patternString);
		
		Matcher matcher = pattern.matcher(content);
		if (matcher.find()) {
			if(matcher.groupCount() > 0){
				ret = matcher.group(1);
			} else {
				ret = matcher.group(0);
			}
		}
		return ret;
	}
	
	/**
	 * 获得字符串中第一个匹配所给正则表达式的值,如果没有,返回空字符串
	 * @param content
	 * @param rgx
	 * @return
	 */
	public static String find(String content, String patternString){
		return find(content, patternString, "");
	}
	
	/**
	 * 获得字符串中所有匹配所给正则表达式的值,如果没有,返回null
	 * @param content
	 * @param patternString
	 * @return
	 */
	public static String[] findAll(String content, String patternString){
		List<String> ret = new LinkedList<String>();
		Pattern pattern = getPattern(patternString);
		Matcher matcher = pattern.matcher(content);
		while (matcher.find()) {
			if(matcher.groupCount() > 0){
				ret .add(matcher.group(1));
			} else {
				ret .add(matcher.group(0));
			}
		}
		return ret.toArray(new String[ret.size()]);
	}
	
	/**
	 * 将字符串数组串接成字符串
	 * @param strs
	 * @param spliter
	 * @return
	 */
	public static String join(String[] strs, String spliter){
		StringBuilder sb = new StringBuilder();
		for(String s : strs){
			sb.append(s);
			sb.append(spliter);
		}
		return sb.toString();
	}
	
	public static String subString(String str, int begin, int end){
		if(str == null || str.length() == 0) return str;
		int max = Math.min(end, str.length());
		return str.substring(begin, max);
	}
	
	public static String cutString(String str, int length ,String lastStr){
		String subStr = subString(str, 0, length);
		int i = subStr.lastIndexOf(lastStr);
		if(i != -1){
			return subString(str, 0 , i);
		}else {
			return subStr;
		}
	}
	
	public static int toInt(String s){
		return toInt(s,0);
	}
	
	public static int toInt(String s, int defaultValue){
		try{
			return Integer.parseInt(s);
		} catch (Exception e) {
			return defaultValue;
		}
	}
	
	public static long toLong(String s){
		try{
			return Long.parseLong(s);
		} catch (Exception e) {
			return 0;
		}
	}
	
	public static boolean notEmpty(String s){
		return s != null && s.length() > 0;
	}
	
	
	private static Pattern getPattern(String patternStr){
		Pattern ret = Pattern.compile(patternStr , Pattern.DOTALL);
		return ret;
	}
	
	
	
	
	public static void main(String[] args) {
//		String s = format$("test${1}${0}###${2}", "成0功","成1功");
//		System.out.println(s);
//		Map<String, String> map = new HashMap<String, String>();
//		map.put("key1", "成1功");
//		map.put("key2", "成2功");
//		String s2 = format$("test2${key2}${key1}${key2}${key3}", map);
//		System.out.println(s2);
//		String ori = "abcabccardrg";
//		String[] res = findAll(ori, "a([^e])");
//		for(String s: res){
//			System.out.println(s);
//		}
		String ss= "abc abc abc a";
		System.out.println(cutString(ss, 9, " "));
	}
}
